home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- #include <stdio.h>
- #include <math.h>
- #include <malloc.h>
- #include <GL/gl.h>
-
- #include "quickcull.h"
-
-
- struct _qcDetail {
- int minLod ;
- int maxLod ;
- float minZ ;
- float maxZ ;
- float radius ;
- } ;
-
-
- /* BEGIN PROTOTYPES -S quickcull.c */
- /* END PROTOTYPES -S quickcull.c */
-
-
- static float cpwi ;
- static float spw ;
- static float tpw ;
- static float cphi ;
- static float sph ;
- static float tph ;
- static float zN ;
- static float zF ;
- static float re[3] ;
- static float vl[3] ;
- static float vw[3] ;
- static float vh[3] ;
-
-
- /*------------------------------------------------------------------------------
- * Initialize the viewing volume.
- *----------------------------------------------------------------------------*/
- int
- qcInit(
- float w, /* Half width of view volume at near plane */
- float h, /* Half height of view volume at near plane */
- float zNear, /* Near clipping plane */
- float zFar /* Far clipping plane */
- )
- {
- float lw ;
- float lh ;
-
-
- if( w <= 0.0f || h <= 0.0f || zNear >= zFar || zNear < 0.0f )
- {
- return( 0 ) ;
- }
-
- lw = sqrtf( w * w + zNear * zNear ) ;
- cpwi = lw / zNear ;
- spw = w / lw ;
- tpw = w / zNear ;
-
- lh = sqrtf( h * h + zNear * zNear ) ;
- cphi = lh / zNear ;
- sph = h / lh ;
- tph = h / zNear ;
-
- zN = zNear ;
- zF = zFar ;
-
- return( 1 ) ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Initialize the viewing orientation.
- *----------------------------------------------------------------------------*/
- int
- qcSetView(
- float rEye[3],
- float vL[3],
- float vW[3],
- float vH[3]
- )
- {
- re[0] = rEye[0] ;
- re[1] = rEye[1] ;
- re[2] = rEye[2] ;
-
- vl[0] = vL[0] ;
- vl[1] = vL[1] ;
- vl[2] = vL[2] ;
-
- vw[0] = vW[0] ;
- vw[1] = vW[1] ;
- vw[2] = vW[2] ;
-
- vh[0] = vH[0] ;
- vh[1] = vH[1] ;
- vh[2] = vH[2] ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Test an object for culling (return QC_CULLED if culled, LOD if not)
- *----------------------------------------------------------------------------*/
- int
- qcCull(
- float v[3], /* Object center */
- qcDetail qcd
- )
- {
- float u[3] ;
- float l ;
- float w ;
- float s ;
- float d ;
- float h ;
- float r = qcd->radius ;
- int lod ;
-
- u[0] = v[0] - re[0] ;
- u[1] = v[1] - re[1] ;
- u[2] = v[2] - re[2] ;
-
- l = u[0] * vl[0] + u[1] * vl[1] + u[2] * vl[2] ;
-
- if( zF < l - r || zN > l + r )
- {
- return( QC_CULLED ) ;
- }
-
- w = u[0] * vw[0] + u[1] * vw[1] + u[2] * vw[2] ;
- if( w < 0.0f )
- {
- w = -w ;
- }
-
- d = w * cpwi ;
- s = ( l + w * tpw ) * spw ;
-
- if( s < d -r )
- {
- return( QC_CULLED ) ;
- }
-
- h = u[0] * vh[0] + u[1] * vh[1] + u[2] * vh[2] ;
- if( h < 0.0f )
- {
- h = -h ;
- }
-
- d = h * cphi ;
- s = ( l + h * tph ) * sph ;
-
- if( s < d -r )
- {
- return( QC_CULLED ) ;
- }
-
- if( l <= qcd->minZ )
- {
- lod = qcd->minLod ;
- }
- else if( l >= qcd->maxZ )
- {
- lod = qcd->maxLod ;
- }
- else
- {
- lod = qcd->minLod + (int)( 0.5f +
- ( (float)( qcd->maxLod - qcd->minLod )
- * ( l - qcd->minZ ) / ( qcd->maxZ - qcd->minZ ) ) ) ;
- }
-
- return( lod ) ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Drawing bounding square of view volume.
- *----------------------------------------------------------------------------*/
- void
- qcDraw(
- float z
- )
- {
- float c[3] ;
- float dw[3] ;
- float dh[3] ;
- float w ;
- float h ;
-
- c[0] = re[0] + z * vl[0] ;
- c[1] = re[1] + z * vl[1] ;
- c[2] = re[2] + z * vl[2] ;
-
- w = tpw * z ;
- dw[0] = w * vw[0] ;
- dw[1] = w * vw[1] ;
- dw[2] = w * vw[2] ;
- h = tph * z ;
- dh[0] = h * vh[0] ;
- dh[1] = h * vh[1] ;
- dh[2] = h * vh[2] ;
-
- glBegin( GL_LINE_LOOP ) ;
- glVertex3f(c[0]+dw[0]+dh[0],c[1]+dw[1]+dh[1],c[2]+dw[2]+dh[2]);
- glVertex3f(c[0]-dw[0]+dh[0],c[1]-dw[1]+dh[1],c[2]-dw[2]+dh[2]);
- glVertex3f(c[0]-dw[0]-dh[0],c[1]-dw[1]-dh[1],c[2]-dw[2]-dh[2]);
- glVertex3f(c[0]+dw[0]-dh[0],c[1]+dw[1]-dh[1],c[2]+dw[2]-dh[2]);
- glEnd() ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Create and initialize a qcDetail structure.
- *----------------------------------------------------------------------------*/
- qcDetail
- qcCreateDetail(
- int minLod,
- int maxLod,
- float minZ,
- float maxZ,
- float radius
- )
- {
- qcDetail qcd ;
-
- if( ( qcd = (qcDetail)malloc( sizeof( struct _qcDetail ) ) ) == NULL )
- {
- return( NULL ) ;
- }
-
- qcSetLodRange( qcd, minLod, maxLod ) ;
-
- qcd->minZ = minZ ;
- qcd->maxZ = maxZ ;
- qcd->radius = radius ;
-
- return( qcd ) ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Modify the lod range for a qcDetail.
- *----------------------------------------------------------------------------*/
- void
- qcSetLodRange(
- qcDetail qcd,
- int minLod,
- int maxLod
- )
- {
- if( minLod < 0 || maxLod < minLod )
- {
- fprintf( stderr, "qcCreateDetail: bad LOD range\n" ) ;
- }
-
- qcd->minLod = minLod ;
- qcd->maxLod = maxLod ;
- }
-